Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Nodecaf is a light framework for developing RESTful Apps in a quick and convenient manner.
Docs for version v0.13.x
Nodecaf is a light framework for developing RESTful Apps in a quick and convenient manner.
npm i -P -g nodecaf-cli
.nodecaf init my-project
.lib/main.js
const Nodecaf = require('nodecaf');
const routes = require('./routes');
module.exports = () => new Nodecaf({
// Optionally bind to a given port
conf: { port: 80 },
// Load your routes.
routes,
// Perform your server initialization logic.
async startup({ conf, log, call }){
},
// Perform your server finalization logic.
async shutdown({ conf, log, call }){
}
});
lib/routes.js
const { post, get, del, head, patch, put, all } = require('nodecaf');
module.exports = [
// Define routes with their handler functions (async or regular no matter).
get('/foo/:f/bar/:b', FooBar.read),
post('/foo/:f/bar', FooBar.write),
// ...
// This route runs whenever there is no other path match
all(Foo.atLast)
];
nodecaf run .
There are a few supported ways of running your app dependng on the type of environment you are targeting.
npm i -P -g nodecaf-cli
)nodecaf run path/to/your/app
-c path/to/config
-r
Dockerfile
command
/app
inside the containerOr use this example compose configuration:
my-app:
build: ./my-app
command: -c /my-conf.toml
ports:
- 80:8080
volumes:
- ./my-conf.toml:/my-conf.toml
- ./my-app:/app
environment:
NODE_ENV: ''
Dockerfile
in the same fashion as developmentcommand
are accessible inside the containerYour Nodecaf app is exported as a regular node module, so it can run as a dependency in another project
let myApp = require('my-app');
(async function(){
let app = myApp();
await app.start();
let res = await app.trigger('/');
await app.stop();
})();
If you have found any problems with Nodecaf, please:
~bug
or ~security
.We will make sure to take a look when time allows us.
If you wish to get that awesome feature or have some advice for us, please:
~proposal
.If you have spotted any enhancements to be made and is willing to get your hands dirty about it, fork us and submit your merge request so we can collaborate effectively.
Formerly based on Express, Nodecaf has a simpler approach to defining routes, offloading much of the complexity to the already existing code partitioning idioms (i.e. functions). Check out how to use all the awesome goodies Nodecaf introduces.
In this manual we address as handler args the keys in the object passed as the only argument of any route handler function. The code below shows all handler args exposed by Nodecaf:
function({ method, path, res, query, params, body, conf, log, headers, call, websocket }){
// Do your stuff.
}
Quick reference:
res
: An object containing the functions to send a response to the client.path
, method
, query
, params
, body
, headers
: Properties of the request.
They contain respectively the requested path, HTTP method, query string, the URL parameters, and the request body data.conf
: This object contains the entire
application configuration data.log
: A logger instance. Use it to log events of
your application.call
: Calls any user function passing the handler args as the first argument.
Signature: call(userFunc, ...extraArgs)
.Nodecaf allow you to read a configuration file and use it's data in all routes and server configuration.
Use this feature to manage:
Suported config formats: TOML, YAML, JSON, CSON
Check out how to generate a project with configuration file already plugged in
To load a config file in your app, use the -c
flag through the CLI pointing
to your conf file path: nodecaf run -c my/conf/path.toml my/app
You can use the config data through it's handler arg in all route handlers as follows:
post('/foo', function({ conf }){
console.log(conf.key); //=> 'value'
})
Config data can also be passed as an object to the app constructor in lib/main.js
:
module.exports = () => new Nodecaf({ conf: { key: 'value' } });
Or a file path if you want to have a fixed config file for setting defaults or any other reason:
module.exports = () => new Nodecaf({ conf: __dirname + '/default.toml' });
You can also use the app.setup
to add a given configuration
file or object on top of the current one as follows:
app.setup('/path/to/settings.toml');
app.setup('/path/to/settings.yaml');
app.setup({ key: 'value' });
app.setup({ key: 'new-value', foo: 'bar' });
Layering is useful, for example, to keep a default settings file in your server source code to be overwritten by your user's.
Nodecaf logs events to stdout by default where each line of the ouput is a JSON object.
The log entries will have some default predefined values like pid, hostname etc...
In your route handlers, use the functions available in the log
object as follows:
function({ log }){
log.info('hi');
log.warn({ lang: 'fr' }, 'au revoir');
log.fatal({ err: new Error() }, 'The error code is %d', 1234);
}
Below is described the signature of the available logging methods.
debug
, info
, warn
, error
, fatal
)Nodecaf will automatically log some useful server events as described in the table below:
Type | Level | Event |
---|---|---|
error after headers sent | warn | An error happened inside a route after the headers were already sent |
route | error | An error happened inside a route and was not caught |
crash | fatal | An error happened that crashed the server process |
request | debug | A request has arrived |
response | debug | A response has been sent |
app | debug | The application is starting up |
app | info | The application has started |
app | info | The application has stopped |
app | info | The application configuration has been reloaded |
event | warn | Called res.end() after response was already finished |
Additionally, you can filter log entries by level and type with the following settings:
[log]
level = 'warn' # Only produce log entries with level 'warn' or higher ('error' & 'fatal')
type = 'my-type' # Only produce log entries with type matching exactly 'my-type'
You can disable logging entirely for a given app by setting it to false
in the config
log = false
Nodecaf accepts async functions as well as regular functions as route handlers. All rejections/error within your async handler will be gracefully handled. You will be able to avoid callback hell without creating bogus adapters for your promises.
get('/my/thing', function({ res }){
res.end('My regular function works!');
})
get('/my/other/thing', async function({ res }){
await myAsyncThing();
res.end('My async function works too!');s
})
In Nodecaf, any uncaught synchronous error happening inside route handler will be automatically converted into a harmless RESTful 500.
post('/my/thing', function(){
throw new Error('Should respond with a 500');
})
To support the callback error pattern, use the res.error()
function arg.
const fs = require('fs');
post('/my/thing', function({ res }){
fs.readFile('./my/file', 'utf8', function(err, contents){
if(err)
return res.error(err);
res.end(contents);
});
})
To use other HTTP status codes you can send an integer in the first parameter of
res.error()
.
post('/my/thing', function({ error }){
try{
doThing();
}
catch(e){
error(404, 'Optional message for the response');
}
})
Nodecaf provides you with an assertion module containing functions to generate the most common REST outputs based on some condition. Check an example to trigger a 404 in case a database record doesn't exist.
get('/my/thing/:id', function({ params, db, res }){
let thing = await db.getById(params.id);
res.notFound(!thing, 'thing not found');
doStuff();
})
If the record is not found, the res.notfound()
call will stop the route execution right
away and generate a RESTful NotFound
error.
Along with notFound
, the following assertions with similar behavior are provided:
Method | Status Code |
---|---|
badRequest | 400 |
unauthorized | 401 |
forbidden | 403 |
notFound | 404 |
conflict | 409 |
gone | 410 |
badType | 415 |
Nodecaf makes it simple to share global objects (eg.: database connections,
instanced libraries) across all route handlers. In your lib/main.js
you can
expose an object of which all keys will become handler args.
module.exports = () => new Nodecaf({
startup({ global }){
global.db = myDbConnection;
global.libX = new LibXInstance();
}
});
Then in all routes you can:
get('/my/thing', function({ db, libX }){
// use your global stuff
})
Nodecaf provides a setting to enable permissive CORS on all routes. Defaults to disabled. In your conf file:
cors = true
cors = 'my://origin'
cors = [ 'my://origin1', 'my://origin2' ]
Setup the cors according to the popular CORS Express middleware.
Use the websocket
handler argument to expect a Websocket upgrade.
get('/my/ws/endpoint', async ({ websocket }) => {
// Wait till ws connection is open
const ws = await websocket();
ws.on('message', m => {
ws.send('Hello World!');
ws.close();
});
})
Property | Type | Description | Default |
---|---|---|---|
app.conf.delay | Integer | Milliseconds to wait before actually starting the app | 0 |
app.conf.port | Integer | Port for the web server to listen (also exposed as user conf) | 80 or 443 |
app.conf.cookie.secret | String | A secure random string to be used for signing cookies | none |
opts.name | String | Manually set application name used in various places | package.json s |
opts.version | String | Manually set application version | package.json s |
opts.shouldParseBody | Boolean | Wether supported request body types should be parsed | true |
[v0.13.3] - 2023-08-22
signed
option of res.cookie()
body.raw()
res.end()
being called more than onceapp.stop()
to preserve globals so callbacks trying to access them don't failFAQs
Nodecaf is a light framework for developing RESTful Apps in a quick and convenient manner.
The npm package nodecaf receives a total of 567 weekly downloads. As such, nodecaf popularity was classified as not popular.
We found that nodecaf demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.